#ifndef	___MSG_BUFFER___
#define ___MSG_BUFFER___

#include "Entry/LibExportCom.h"

#pragma warning(push)
#pragma warning(disable:4275)
#pragma warning(disable:4251)



#define MSG_BUFF_SIZE 1024


class TCOM_API MsgBuffer	:	public std::streambuf
{
public:
	typedef boost::asio::const_buffers_1 const_buffers_type;
	typedef boost::asio::mutable_buffers_1 mutable_buffers_type;

	MsgBuffer()
	{
		setg(buffer_, buffer_, buffer_ + MSG_BUFF_SIZE);
		setp(buffer_, buffer_ + MSG_BUFF_SIZE);
	}

	std::size_t size() const
	{
		return pptr() - gptr();
	}

	std::size_t max_size() const
	{
		return MSG_BUFF_SIZE;
	}

	mutable_buffers_type prepare(std::size_t n = MSG_BUFF_SIZE)
	{
		return boost::asio::buffer(boost::asio::mutable_buffer(pptr(), MSG_BUFF_SIZE));
	}

	const_buffers_type data() const
	{
		return boost::asio::buffer(boost::asio::const_buffer(gptr(), (pptr() - gptr()) ));
	}

	void commit(std::size_t n)
	{
		if (pptr() + n > epptr())
			n = epptr() - pptr();
		pbump(static_cast<int>(n));
		setg(eback(), gptr(), pptr());
	}

	void consume(std::size_t n)
	{
		if (gptr() + n > pptr())
			n = pptr() - gptr();
		gbump(static_cast<int>(n));
	}

	void update_buffer_length4() 	
	{ 		
		short val = size(); 		
		memcpy(gptr()+4, (char*)&val, 2);  	
	}
protected:
	enum { buffer_delta = 128 };

	int_type underflow()
	{
		if (gptr() < pptr())
		{
			setg(&buffer_[0], gptr(), pptr());
			return traits_type::to_int_type(*gptr());
		}
		else
		{
			return traits_type::eof();
		}
	}


	int_type overflow(int_type c)
	{
		// detail in boost buffer
		return traits_type::not_eof(c);
	}

	void reserve(std::size_t n)
	{
		//	detail in boost buffer
	}
private:
	char buffer_[MSG_BUFF_SIZE];
};


typedef boost::object_pool<MsgBuffer>	MsgBufferFactory;

#pragma warning(pop)

#endif
